/*
 * @FileName: loop.h
 * @Author: GreyQiu qiushaogui@aikosolar.com
 * @Date: 2023-07-12 16:05:59
 * @LastEditors: GreyQiu qiushaogui@aikosolar.com
 * @LastEditTime: 2023-09-14 11:10:42
 * @Description: 
 * 
 * Copyright (c) 2023, All Rights Reserved. 
 */

#ifndef __LOOP_H__
#define __LOOP_H__

#include "bsp.h"
#include "easy_pid_f32.h"
#include "easy_filter.h"
#include "bsp_pwm.h"
#include "dev_info.h"
#include "app_mppt.h"
#include "app_analog.h"


typedef enum {
    MUX_NONE = 0, // 无环路竞争成功，所有环路饱和
    MUX_VLOOP,
    MUX_ILOOP,
    MUX_GLOOP
} mux_t;

typedef struct {
    easy_pid_f32_t vin;
    easy_pid_f32_t current;
    easy_pid_f32_t vout;
    uint16_t en;
} boost_controller_t;

extern boost_controller_t controller[BOOST_NUM];

static inline float controller_run(boost_controller_t * controller, float vin, float iin, float vout)
{
    float iref, duty1, duty2;
    iref = easy_pid_run(&controller->vin, controller->vin.ref - vin);
    easy_pid_set_ref(&controller->current, iref);
    if (vin < 10) vin = 10;
    duty1 = easy_pid_run(&controller->current, controller->current.ref - iin) / 50;
    duty2 = easy_pid_run(&controller->vout, controller->vout.ref - vout) / 50;

    if (duty1 > duty2) {
        duty1 = duty2;
    }
    return duty1;
}

static inline void loop_clear(easy_pid_f32_t * obj)
{
    easy_pid_clear_f32(obj);
}

static inline void loop_setRef(easy_pid_f32_t * obj, float ref)
{
    easy_pid_set_ref(obj, ref);
}

static inline void controller_enable(boost_controller_t * controller)
{
    controller->en = true;
}

static inline void controller_disable(boost_controller_t * controller)
{
    controller->en = false;
}

static inline uint16_t controller_isEnable(boost_controller_t * controller)
{
    return controller->en;
}

void loop_init(void);

#endif // __LOOP_H__

